package com.shijie.utils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.joda.time.DateTime;
import org.springframework.util.Assert;

import com.shijie.core.ResultCode;
import com.shijie.core.ServiceException;

/**
 * Created with Yang Huan
 * Date: 2017/3/2
 * Time: 11:34
 */
public class DateUtil {

    private static ThreadLocal<DateFormat> dateFormatHolder = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

    public static Date toDate(String s) throws ServiceException {
        Assert.hasText(s, "参数不能为空");
        try {
            return dateFormatHolder.get().parse(s);
        } catch (Exception e) {
            throw new ServiceException(ResultCode.FAIL, e.getMessage());
        }
    }

    public static Date toDate(String s, String formatter) throws ServiceException {
        Assert.hasText(s, "参数不能为空");
        try {
            return new SimpleDateFormat(formatter).parse(s);
        } catch (Exception e) {
            throw new ServiceException(ResultCode.FAIL, e.getMessage());
        }
    }

    public static Long toLong(String s) throws ServiceException {
        Date date = toDate(s);
        if (date == null) {
            return 0L;
        }
        return date.getTime();
    }

    public static String toString(Date date) {
        if (date == null) {
            return null;
        }
        return dateFormatHolder.get().format(date);
    }

    public static String toString(Date date, String formatter) {
        if (date == null) {
            return null;
        }
        return new SimpleDateFormat(formatter).format(date);
    }

    public static Date addDays(Date src, Integer days) {
        Date target = null;
        if (src != null && days != null) {
            Calendar rightNow = Calendar.getInstance();
            rightNow.setTime(src);
            rightNow.add(Calendar.DAY_OF_YEAR, days);
            target = rightNow.getTime();
        }
        return target;
    }

    public static Date addMonth(Date src, Integer month) {
        Date target = null;
        if (src != null && month != null) {
            Calendar rightNow = Calendar.getInstance();
            rightNow.setTime(src);
            rightNow.add(Calendar.MONTH, month);
            target = rightNow.getTime();
        }
        return target;
    }

    public static Date addHour(Date src, Integer hours) {
        Date target = null;
        if (src != null && hours != null) {
            Calendar rightNow = Calendar.getInstance();
            rightNow.setTime(src);
            rightNow.add(Calendar.HOUR, hours);
            target = rightNow.getTime();
        }
        return target;
    }

    public static Date addMinutes(Date src, Integer minutes) {
        Date target = null;
        if (src != null && minutes != null) {
            Calendar rightNow = Calendar.getInstance();
            rightNow.setTime(src);
            rightNow.add(Calendar.MINUTE, minutes);
            target = rightNow.getTime();
        }
        return target;
    }

    public static Date addTime(Date src, Date time) throws ServiceException {
        Date target = null;
        if (src != null && time != null) {
            time = DateUtil.toDate(DateUtil.toString(time, "HH:mm:ss"), "HH:mm:ss");
            target = new Date(src.getTime() + time.getTime() - DateUtil.toDate("0:0:0", "HH:mm:ss").getTime());
        }
        return target;
    }

    public static Integer getWeekDay(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        int dayForWeek;
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            dayForWeek = 7;
        } else {
            dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        }
        return dayForWeek;
    }

    public static Integer getMonthDay(Date time) {
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    public static Date addSecond(Date src, Integer value) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(src);
        calendar.add(Calendar.SECOND, value);
        src = calendar.getTime();
        return src;
    }

    public static int subTimeMinute(Date src1, Date src2) {
        return (int) ((src1.getTime() - src2.getTime()) / (1000 * 60));
    }

    public static int subTimeDay(Date src1, Date src2) {
        return (int) ((src1.getTime() - src2.getTime()) / (1000 * 60 * 60 * 24));
    }

    public static List<String> getDaysBetweenStartAndEnd(Date applyStart,Date applyEnd) {
    	List<String> xAxis = new ArrayList<>();
    	DateTime dt = new  DateTime(applyStart);
    	xAxis.add((dt.getMonthOfYear()>=10?dt.getMonthOfYear():"0"+dt.getMonthOfYear()) +"月"+(dt.getDayOfMonth()>=10?dt.getDayOfMonth():"0"+dt.getDayOfMonth()) +"日");
    	while(true) {
    		dt = dt.plusDays(1);
    		if(dt.isBefore(applyEnd.getTime())) {
    			xAxis.add((dt.getMonthOfYear()>=10?dt.getMonthOfYear():"0"+dt.getMonthOfYear()) +"月"+(dt.getDayOfMonth()>=10?dt.getDayOfMonth():"0"+dt.getDayOfMonth())+"日");
    			continue;
    		}
    		break;
    	}
    	dt = new  DateTime(applyEnd);
    	String week =(dt.getMonthOfYear()>=10?dt.getMonthOfYear():"0"+dt.getMonthOfYear()) +"月"+(dt.getDayOfMonth()>=10?dt.getDayOfMonth():"0"+dt.getDayOfMonth())+"日";
    	if(!xAxis.contains(week)) {
    		xAxis.add(week);
    	}
    	return xAxis;
    }
    
    public static List<String> getMonthsBetweenStartAndEnd(Date applyStart,Date applyEnd) {
    	List<String> xAxis = new ArrayList<>();
    	DateTime dt = new  DateTime(applyStart);
    	xAxis.add(dt.getYear()+"年"+(dt.getMonthOfYear()>=10?dt.getMonthOfYear():"0"+dt.getMonthOfYear()) +"月");
    	while(true) {
    		dt = dt.plusMonths(1);
    		if(dt.isBefore(applyEnd.getTime())) {
    			xAxis.add(dt.getYear()+"年"+(dt.getMonthOfYear()>=10?dt.getMonthOfYear():"0"+dt.getMonthOfYear()) +"月");
    			continue;
    		}
    		break;
    	}
    	dt = new  DateTime(applyEnd);
    	String week =dt.getYear()+"年"+(dt.getMonthOfYear()>=10?dt.getMonthOfYear():"0"+dt.getMonthOfYear()) +"月";
    	if(!xAxis.contains(week)) {
    		xAxis.add(week);
    	}
    	return xAxis;
    }
    
    public  static void main(String[] args){
    	System.out.println(DateUtil.getMonthsBetweenStartAndEnd(DateTime.now().minusDays(12).toDate(), DateTime.now().toDate()));
    }
}
